import * as THREE from 'three';
import * as dat from 'dat.gui'
import './index.css'

/**
 * Debug
 */
const gui = new dat.GUI({
    width: 300
})

// 轨道控制器
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';

// Canvas
const canvas = document.querySelector("canvas.webgl");

// Scene
const scence = new THREE.Scene();

// Object
const geometry1 = new THREE.PlaneGeometry(1,1)
const geometry2 = new THREE.SphereGeometry(0.5,36,12)
const geometry3 = new THREE.TorusGeometry(0.3, 0.2, 16, 100)

//LoadingManager
const loadingManager = new THREE.LoadingManager();
loadingManager.onStart = (url, itemsLoaded, itemsTotal) => {
    console.log(`Started loading file: ${url}.\nLoaded ${itemsLoaded} of ${itemsTotal} files.`)
}
loadingManager.onProgress = (url, itemsLoaded, itemsTotal) => {
    console.log(`Loading file: ${url}.\nLoaded ${itemsLoaded} of ${itemsTotal} files.`)
}
loadingManager.onLoad = () => {
    console.log('Loading complete!')
}
loadingManager.onError = (url) => {
    console.log(`There was an error loading ${url}`)
}


const textureLoader = new THREE.TextureLoader()
const doorColorTexture = textureLoader.load('../assets/textures/door/color.jpg')
const alphaTexture = textureLoader.load('../assets/textures/door/alpha.jpg')
const ambientOcclusionTexture = textureLoader.load('../assets/textures/door/ambientOcclusion.jpg')
const heightTexture = textureLoader.load('../assets/textures/door/height.jpg')
const metalnessTexture = textureLoader.load('../assets/textures/door/metalness.jpg')
const roughnessTexture = textureLoader.load('../assets/textures/door/roughness.jpg')
const normalTexture = textureLoader.load('../assets/textures/door/normal.jpg')

// MeshBasicMaterial 基础网格材质

// const material = new THREE.MeshBasicMaterial()
// material.map = doorColorTexture
// material.color = new THREE.Color('#ff0fff') //颜色
// material.wireframe = true  //网格
// material.transparent = true  //开启透明
// material.opacity = 0.5    //设置透明度
// material.alphaMap = alphaTexture  //alpha贴图是一张灰度纹理，用于控制整个表面的不透明度。（黑色：完全透明；白色：完全不透明）。 默认值为 null。
// material.side = THREE.DoubleSide  //双面可见   正面FrontSide  背面BackSide     将摄像机放在立方体内部，side设置为BackSide  就是3D看房的原理



// MeshNormalMaterial 法线网格材质 把法线向量映射到RGB的材质

// const material = new THREE.MeshNormalMaterial()
// material.flatShading = true //平面着色进行渲染 默认值为false


// MeshDepthMaterial 深度网格材质  离相机越近，越白   离相机越远 越黑
// const material = new THREE.MeshDepthMaterial()
// // 加入光源
const ambientLight = new THREE.AmbientLight('#ffffff', 0.5)
scence.add(ambientLight)
const pointLight = new THREE.PointLight('#ffffff', 0.5)
pointLight.position.set(2,3,4)
scence.add(pointLight)


// MeshStandardMaterial 标准材质网格
const material = new THREE.MeshStandardMaterial()
material.metalness = 0.5 //金属度
material.roughness = 0.5  //粗糙度


gui.add(material,'metalness').min(0).max(1).step(0.001)
gui.add(material,'roughness').min(0).max(1).step(0.001)


// map
material.map = doorColorTexture


// aoMap ambient occlusion map
// aoMap需要第二组UV
// geometry1.setAttribute('uv2',new THREE.BufferAttribute(geometry1.attributes.uv.array,2))
// geometry2.setAttribute('uv2',new THREE.BufferAttribute(geometry2.attributes.uv.array,2))
// geometry3.setAttribute('uv2',new THREE.BufferAttribute(geometry3.attributes.uv.array,2))
// aoMap  环境阴影
material.aoMap = ambientOcclusionTexture
material.aoMapIntensity  = 1
gui.add(material,'aoMapIntensity').min(0).max(1).step(0.1)


// displacementMap 位移贴图
material.displacementMap  = heightTexture
material.displacementScale = 0.05
gui.add(material,'displacementScale').min(0).max(1).step(0.01)


// 金属度、粗糙度
material.metalnessMap = metalnessTexture
material.roughnessMap = roughnessTexture

// normalMap 法线贴图
material.normalMap = normalTexture
material.normalScale.set(0.5, 0.5)

// alphaMap 控制是否透明 白色不透明  黑色透明
material.alphaMap = alphaTexture
material.transparent = true


const mesh1 = new THREE.Mesh(geometry1,material)
const mesh2 = new THREE.Mesh(geometry2,material)
mesh2.position.set(-1.5,0,0)
const mesh3 = new THREE.Mesh(geometry3,material)
mesh3.position.set(1.5,0,0)
scence.add(mesh1,mesh2,mesh3)


// Sizes
const Sizes = {
    width: window.innerWidth,
    height: window.innerHeight
}

window.addEventListener('resize', () => {
    // Update size
    Sizes.width = window.innerWidth
    Sizes.height = window.innerHeight

    // Update camera
    camera.aspect = Sizes.width / Sizes.height
    camera.updateProjectionMatrix()

    // Updaet renderer
    renderer.setSize(Sizes.width, Sizes.height)
    renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
})


const camera = new THREE.PerspectiveCamera(75, Sizes.width / Sizes.height, 1, 100)

// 相机的初始位置在（0，0，0）中心点，看不见物体，移动相机
camera.position.z = 3
scence.add(camera)

// Controls
const controls = new OrbitControls(camera, canvas);
controls.enableDamping = true  //添加阻尼效果  修改之后需要update

// Renderer
const renderer = new THREE.WebGLRenderer({
    canvas,
})
renderer.setSize(Sizes.width, Sizes.height);
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))  //解决抗锯齿,不需要超过2，避免性能浪费 

const tick = () => {
    controls.update()
    // Render
    renderer.render(scence, camera);
    window.requestAnimationFrame(tick);
}

tick()